use eframe::egui;
use std::fs;
use std::io::{self, Seek, SeekFrom, Write};
use std::path::{Path, PathBuf};
use std::time::Instant;
use rfd::FileDialog;

fn main() {
    let options = eframe::NativeOptions {
        viewport: egui::ViewportBuilder::default().with_inner_size([320.0, 240.0]),
        ..Default::default()
    };
    // 处理 eframe::run_native 的返回结果
    let _ = eframe::run_native(
        "文件夹遍历工具",
        options,
        Box::new(|cc| {
            // 加载支持中文的字体
            cc.egui_ctx.set_fonts({
                let mut fonts = egui::FontDefinitions::default();
                fonts.font_data.insert(
                    "simhei".to_owned(),
                    egui::FontData::from_static(include_bytes!("../simhei.ttf")).into(),
                );
                fonts.families
                    .get_mut(&egui::FontFamily::Proportional)
                    .unwrap()
                    .insert(0, "simhei".to_owned());
                fonts
            });

            Ok(Box::new(FolderTraverserApp::default()))
        }),
    );
}

#[derive(Default)]
struct FolderTraverserApp {
    selected_folder: Option<PathBuf>,
    traversing: bool,
    elapsed_time: Option<f64>,
    show_error: bool,
    total_folders: u32,
    total_files: u32,
}

impl FolderTraverserApp {
    fn traverse_folder(&mut self) {
        if let Some(folder) = self.selected_folder.clone() {
            self.traversing = true;
            self.total_folders = 0;
            self.total_files = 0;
            let start = Instant::now();

            // 指定 log 文件夹路径
            let log_dir = Path::new(r"C:\Users\Administrator\Desktop\log");
            if !log_dir.exists() {
                fs::create_dir_all(&log_dir).expect("无法创建日志目录");
            }

            // 生成日志文件名
            let log_file_name = format!(
                "{}.txt",
                folder.file_name().unwrap_or_else(|| std::ffi::OsStr::new("unknown")).to_string_lossy()
            );
            let log_file_path = log_dir.join(log_file_name);

            // 打开日志文件
            let mut log_file = fs::File::create(&log_file_path).expect("无法创建日志文件");

            // 遍历文件夹
            self.traverse_recursive(&folder, &mut log_file, 0).expect("无法遍历文件夹");

            // 记录耗时
            let elapsed = start.elapsed();
            self.elapsed_time = Some(elapsed.as_secs_f64());
            self.traversing = false;

            // 在日志文件第一行写入统计信息
            let mut log_file = fs::OpenOptions::new()
                .write(true)
                .read(true)
                .open(&log_file_path)
                .expect("无法打开日志文件以写入统计信息");
            log_file.seek(SeekFrom::Start(0)).expect("无法定位到文件开头");
            let mut log_file = io::BufWriter::new(log_file);
            writeln!(
                log_file,
                "总共文件夹: {}, 总共文件: {}, 用时: {:.2}s",
                self.total_folders,
                self.total_files,
                self.elapsed_time.unwrap()
            )
                .expect("无法将统计信息写入日志文件");
        } else {
            // 如果没有选择文件夹，标记显示错误提示
            self.show_error = true;
        }
    }

    fn traverse_recursive(
        &mut self,
        path: &Path,
        log_file: &mut fs::File,
        depth: u32,
    ) -> io::Result<()> {
        let indent = "  ".repeat(depth as usize);
        if path.is_dir() {
            self.total_folders += 1;
            writeln!(log_file, "{}{} (文件夹)", indent, path.display())?;
            for entry in fs::read_dir(path)? {
                let entry = entry?;
                let entry_path = entry.path();
                self.traverse_recursive(&entry_path, log_file, depth + 1)?;
            }
        } else {
            self.total_files += 1;
            writeln!(log_file, "{}{} (文件)", indent, path.display())?;
        }
        Ok(())
    }
}

impl eframe::App for FolderTraverserApp {
    fn update(&mut self, ctx: &egui::Context, _frame: &mut eframe::Frame) {
        egui::CentralPanel::default().show(ctx, |ui| {
            ui.heading("文件夹遍历工具");

            if ui.button("选择文件夹").clicked() {
                if let Some(folder) = FileDialog::new().pick_folder() {
                    self.selected_folder = Some(folder);
                }
            }

            if let Some(folder) = &self.selected_folder {
                ui.label(format!("已选择文件夹: {}", folder.display()));
            }

            if ui
                .add_enabled(!self.traversing, egui::Button::new("遍历文件夹"))
                .clicked()
            {
                self.traverse_folder();
            }

            if ui.button("重置").clicked() {
                self.selected_folder = None;
                self.elapsed_time = None;
                self.total_folders = 0;
                self.total_files = 0;
            }

            if self.traversing {
                ui.label("正在遍历文件夹...");
            } else if let Some(elapsed) = self.elapsed_time {
                ui.label(format!(
                    "遍历完成，共用时 {:.2} 秒。总共文件夹: {}, 总共文件: {}",
                    elapsed,
                    self.total_folders,
                    self.total_files
                ));
            }
        });

        if self.show_error {
            egui::Window::new("错误提示")
                .open(&mut self.show_error)
                .show(ctx, |ui| {
                    ui.label("请选择文件夹");
                });
        }
    }
}